/**
 * 隧道计算服务模块
 * 提供隧道工程相关的计算服务，作为IPC通信和算法实现之间的桥梁
 * 负责参数验证、算法调用和结果格式化，确保计算结果的准确性和一致性
 */
import { TunnelAlgorithms } from '../../algorithms/tunnel/tunnel';
import { TunnelSurroundingRockAlgorithms } from '../../algorithms/tunnel/tunnelSurroundingRock';

/**
 * 隧道计算服务类
 * 封装隧道工程中各种计算功能，处理计算请求并返回标准化的结果
 * 提供错误处理和结果格式化，使前端能够方便地使用计算结果
 */
export class TunnelCalculatorService {
  /**
   * 计算隧道长度
   * 基于三维坐标计算隧道入洞口到出洞口的空间距离
   * 使用三维欧几里得距离公式进行精确计算
   * 
   * @param {Object} params 计算参数对象
   * @param {number} params.entranceX 入洞口X坐标(m)
   * @param {number} params.entranceY 入洞口Y坐标(m)
   * @param {number} params.entranceZ 入洞口Z坐标(m)
   * @param {number} params.exitX 出洞口X坐标(m)
   * @param {number} params.exitY 出洞口Y坐标(m)
   * @param {number} params.exitZ 出洞口Z坐标(m)
   * @returns {Promise<{success: boolean, data?: number, error?: string}>} 计算结果对象
   * @returns {boolean} return.success - 计算是否成功
   * @returns {number} return.data - 计算成功时返回隧道长度(m)
   * @returns {string} return.error - 计算失败时返回错误信息
   */
  static async calculateTunnelLength(params: any) {
    try {
      // 解构参数，提取隧道入口和出口的三维坐标
      const { entranceX, entranceY, entranceZ, exitX, exitY, exitZ } = params;
      
      // 调用算法类中的静态方法进行隧道长度计算
      // 传入六个坐标参数以计算三维空间中的隧道长度
      const result = TunnelAlgorithms.calculateTunnelLength(
        entranceX,
        entranceY,
        entranceZ,
        exitX,
        exitY,
        exitZ
      );
      
      // 返回成功结果，包含计算得到的隧道长度
      return {
        success: true,
        data: result
      };
    } catch (error: any) {
      // 捕获并处理计算过程中的任何错误
      // 格式化错误信息，确保返回标准化的错误对象
      return {
        success: false,
        error: error.message || '隧道长度计算失败'
      };
    }
  }

  /**
   * 计算隧道埋深类型
   * 根据围岩重度、实际埋深和岩石等级，判断隧道属于深埋还是浅埋类型
   * 并计算临界埋深和垂直均布荷载，为隧道设计提供重要参考依据
   * 
   * @param {Object} params 计算参数对象
   * @param {number} params.gamma 围岩重度(kN/m³)
   * @param {number} params.H 隧道实际埋深(m)
   * @param {number} params.rockgrade 岩石等级(1-6)
   * @returns {Promise<{success: boolean, data?: {depthtype: string, Hp: number, q: number}, error?: string}>} 计算结果对象
   * @returns {boolean} return.success - 计算是否成功
   * @returns {Object} return.data - 计算成功时返回埋深分析结果
   * @returns {string} return.data.depthtype - 埋深类型，'深埋'或'浅埋'
   * @returns {number} return.data.Hp - 临界埋深值(m)
   * @returns {number} return.data.q - 垂直均布荷载(kPa)
   * @returns {string} return.error - 计算失败时返回错误信息
   */
  static async calculateTunnelDepth(params: any) {
    try {
      // 解构参数，提取计算所需的三个关键参数
      const { gamma, H, rockgrade } = params;
      
      // 调用算法类中的静态方法进行隧道埋深计算
      const result = TunnelAlgorithms.TunnelDepth(gamma, H, rockgrade);
      
      // 返回成功结果，包含埋深分析数据
      return {
        success: true,
        data: result
      };
    } catch (error: any) {
      // 捕获并处理计算过程中的任何错误
      return {
        success: false,
        error: error.message || '隧道埋深计算失败'
      };
    }
  }

  /**
   * 计算隧道洞口高程和里程
   * 根据入洞口高程、出洞口高程、明暗线长度和坡度，计算洞口相关参数
   * 
   * @param {Object} params 计算参数对象
   * @param {number} params.entranceZ 入洞口高程(m)
   * @param {number} params.entrancelinelenth 入洞口明暗线长度(m)
   * @param {number} params.exitZ 出洞口高程(m)
   * @param {number} params.exitlinelenth 出洞口明暗线长度(m)
   * @param {number} params.slope 坡度，tan值
   * @returns {Promise<{success: boolean, data?: any, error?: string}>} 计算结果对象
   */
  static async calculateTunnelEntranceExitElevation(params: any) {
    try {
      // 解构参数，提取计算所需的七个关键参数
      const { entranceY, entranceZ, entrancelinelenth, exitY, exitZ, exitlinelenth, slope } = params;
      
      // 参数验证
      if (typeof entranceY !== 'number' || typeof entranceZ !== 'number' || 
          typeof entrancelinelenth !== 'number' || typeof exitY !== 'number' || 
          typeof exitZ !== 'number' || typeof exitlinelenth !== 'number' || 
          typeof slope !== 'number') {
        throw new Error('所有参数必须为有效数字');
      }
      
      // 调用算法类中的静态方法进行隧道洞口高程计算
      const result = TunnelAlgorithms.calculateTunnelEntranceExitElevation(
        entranceZ,
        entranceY,
        entrancelinelenth,
        exitZ,
        exitY,
        exitlinelenth,
        slope
      );
      
      // 返回成功结果，包含洞口参数计算数据
      return {
        success: true,
        data: result
      };
    } catch (error: any) {
      // 捕获并处理计算过程中的任何错误
      return {
        success: false,
        error: error.message || '隧道洞口高程计算失败'
      };
    }
  }
}

/**
 * 隧道围岩计算服务类
 * 封装隧道围岩长度计算相关功能，支持实时计算
 */
export class TunnelSurroundingRockService {
  /**
   * 计算隧道衬砌实际长度
   * 基于围岩分段长度、坡度、进洞口长度和出洞口长度计算衬砌实际长度
   * 实时计算隧道各段衬砌实际长度和总长度，包括洞口长度计算
   * 
   * @param params 计算参数对象
   * @param params.inputs 输入参数数组，包含围岩分段长度、坡度、进洞口长度、出洞口长度
   * @returns {Promise<{success: boolean, data?: {segmentLiningLengths: number[], totalLiningLength: number, entranceAndExitTotal: number}, error?: string}>} 计算结果对象
   */
  static async calculateTunnelLiningLength(params: any) {
    try {
      console.log('TunnelSurroundingRockService: 开始实时计算隧道衬砌长度', { params });
      
      // 参数验证
      if (!params) {
        throw new Error('参数不能为空');
      }
      
      // 只处理新版结构化参数格式
      if (!params.inputs || !Array.isArray(params.inputs)) {
        throw new Error('参数格式错误，必须包含inputs数组');
      }
      
      // 直接使用提供的参数
      const { inputs, slope = 1.0, entranceLength = 0, exitLength = 0 } = params;
      const structuredInput = { inputs, slope, entranceLength, exitLength };
      
      console.log('TunnelSurroundingRockService: 构建的结构化输入参数', structuredInput);
      
      // 异步调用算法进行实时计算
      const result = await TunnelSurroundingRockAlgorithms.calculateLiningLength(structuredInput);
      
      console.log('TunnelSurroundingRockService: 隧道衬砌长度实时计算结果', result);
      
      // 返回成功结果，包含衬砌长度数据
      return {
        success: true,
        data: result
      };
    } catch (error: any) {
      console.error('TunnelSurroundingRockService: 隧道衬砌长度实时计算失败', error);
      // 捕获并处理计算过程中的任何错误
      return {
        success: false,
        error: error.message || '隧道围岩长度计算失败'
      };
    }
  }
}